﻿using Baidu.Aip.Ocr;
using Common.Utility;
using JX3Answering.Entitys;
using Sunny.UI;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using JX3Answering.Common;
using System.Threading.Tasks;
using System.Threading;
using System.Diagnostics;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;

namespace JX3Answering
{
    public partial class AnswertMain : UIForm
    {
        INIFile iNIFile = new INIFile("./Config.ini");
        private float X;//定义当前窗体的宽度
        private float Y;//定义当前窗体的高度

        public AnswertMain()
        {
            InitializeComponent();
            //CheckForIllegalCrossThreadCalls = false;
            //contentText.Watermark = "勾选关键字优化后将会提高答题正确率，但可能会影响查找速度\r\n手动优化每次删除一个关键字进行重新查找，直至查找出答案\r\n自动优化每次删除三个关键字进行重新查找，直至查找出答案";
            xNumText.Text = iNIFile.IniReadValue("CutPosition", "xNum");
            yNumText.Text = iNIFile.IniReadValue("CutPosition", "yNum");
            widthNumText.Text = iNIFile.IniReadValue("CutPosition", "widthNum");
            heightNumText.Text = iNIFile.IniReadValue("CutPosition", "heightNum");
            apiKeyText.Text = iNIFile.IniReadValue("BaiDuApiKey", "apiKey");
            secretKeyText.Text = iNIFile.IniReadValue("BaiDuApiKey", "secretKey");
            apiNumText.Text = iNIFile.IniReadValue("QueryFrequency", "queryNum");

        }
        /// <summary>
        /// 手动查找答案
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void FindAnswerBtn_Click(object sender, EventArgs e)
        {
            try
            {
                titleText.Text = "";
                loadingProcessBar.Visible = true;
                string keyword = CommonMethod.KeyWordOptimization(contentText.Text);
                keyword = CommonMethod.DailyQueryKeyword(keyword);
                if (string.IsNullOrEmpty(keyword))
                {
                    loadingProcessBar.Visible = false;
                    ErrorTip("关键字不能为空！");
                    return;
                }
                if (keywordOptimization.Checked)
                {
                    bool res = true;
                    while (res)
                    {
                        res = QueryAnswering(keyword);
                        if (res)
                        {
                            if (keyword.Length - 1 <= 0)
                            {
                                loadingProcessBar.Visible = false;
                                ErrorTip("暂未找到答案！注意关键字是否正确。");
                                return;
                            }
                            keyword = keyword.Substring(0, keyword.Length - 1);
                        }
                    }
                }
                else
                {
                    if (QueryAnswering(keyword))
                    {
                        loadingProcessBar.Visible = false;
                        ErrorTip("暂未找到答案！注意关键字是否正确。");
                    }

                }

            }
            catch (Exception ex)
            {
                loadingProcessBar.Visible = false;
                ErrorTip(ex.ToString());
            }
        }
        /// <summary>
        /// 自动查找答案
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void autoFindAnswerBtn_Click(object sender, EventArgs e)
        {
            try
            {
                loadingProcessBar.Visible = true;
                string xNumStr = xNumText.Text;
                string yNumStr = yNumText.Text;
                string widthNumStr = widthNumText.Text;
                string heightNumStr = heightNumText.Text;
                string apiKeyStr = apiKeyText.Text;
                string secretKeyStr = secretKeyText.Text;
                if (string.IsNullOrEmpty(xNumStr) || string.IsNullOrEmpty(yNumStr) || string.IsNullOrEmpty(widthNumStr) || string.IsNullOrEmpty(heightNumStr))
                {
                    loadingProcessBar.Visible = false;
                    ErrorTip("设置中的坐标信息不能为空，请检查！");
                    return;
                }
                if (string.IsNullOrEmpty(apiKeyStr) || string.IsNullOrEmpty(secretKeyStr))
                {
                    loadingProcessBar.Visible = false;
                    ErrorTip("设置中的Key不能为空，请检查！");
                    return;
                }
                int xNum = Convert.ToInt32(xNumStr);
                int yNum = Convert.ToInt32(yNumStr);
                int widthNum = Convert.ToInt32(widthNumStr);
                int heightNum = Convert.ToInt32(heightNumStr);
                Bitmap bitmap = GetScreenCapture(xNum, yNum, widthNum, heightNum);
                if (CommonMethod.IsSameImg(bitmap))
                {
                    loadingProcessBar.Visible = false;
                    return;
                }
                titleText.Text = "";
                bitmap.Save(@".\Picture\title.jpg");
                var client = new Ocr(apiKeyStr, secretKeyStr);
                client.Timeout = 60000;
                var image = File.ReadAllBytes(@".\Picture\title.jpg");
                string imageResult = client.GeneralBasic(image).ToString();
                ImageResultEntity imageResultEntity = new ImageResultEntity();
                imageResultEntity = ConvertJson.DeserializeJsonToObject<ImageResultEntity>(imageResult);
                if (imageResultEntity.words_result == null)
                {
                    ErrorEntity errorEntity = new ErrorEntity();
                    errorEntity = ConvertJson.DeserializeJsonToObject<ErrorEntity>(imageResult);
                    ErrorTip($"{errorEntity.error_msg}, Key错误！可以参考下载界面中问题记录的第四个问题查看key是否生效。");
                    loadingProcessBar.Visible = false;
                    return;
                }
                contentText.Text = CommonMethod.KeyWordOptimization(imageResultEntity.words_result[0].words);
                string keyword = CommonMethod.DailyQueryKeyword(contentText.Text);
                if (string.IsNullOrEmpty(keyword))
                {
                    loadingProcessBar.Visible = false;
                    ErrorTip("关键字不能为空！");
                    return;
                }
                if (autoKeywordOptimization.Checked)
                {
                    bool res = true;
                    while (res)
                    {
                        res = QueryAnswering(keyword);
                        if (res)
                        {
                            if (keyword.Length - 3 <= 0)
                            {
                                loadingProcessBar.Visible = false;
                                ErrorTip("暂未找到答案！注意关键字是否正确。");
                                return;
                            }
                            keyword = keyword.Substring(0, keyword.Length - 3);
                        }
                    }
                }
                else
                {
                    if (QueryAnswering(keyword))
                    {
                        loadingProcessBar.Visible = false;
                        ErrorTip("暂未找到答案！注意关键字是否正确。");
                    }
                }
                UpdateCurrentMonthApiNum();
            }
            catch (Exception ex)
            {
                loadingProcessBar.Visible = false;
                ErrorTip(ex.ToString());
                UpdateCurrentMonthApiNum();
            }
        }

        /// <summary>
        /// 截取图片
        /// </summary>
        /// <param name="xNum">X坐标</param>
        /// <param name="yNum">Y坐标</param>
        /// <param name="widthNum">宽度</param>
        /// <param name="heightNum">高度</param>
        /// <returns></returns>
        private static Bitmap GetScreenCapture(int xNum, int yNum, int widthNum, int heightNum)
        {
            Rectangle tScreenRect = new Rectangle(xNum, yNum, widthNum, heightNum);
            Bitmap tSrcBmp = new Bitmap(tScreenRect.Width, tScreenRect.Height); // 用于屏幕原始图片保存
            Graphics gp = Graphics.FromImage(tSrcBmp);
            gp.CopyFromScreen(xNum, yNum, 0, 0, tScreenRect.Size);
            gp.DrawImage(tSrcBmp, xNum, yNum, tScreenRect, GraphicsUnit.Pixel);
            return tSrcBmp;
        }

        private void saveInfobtn_Click(object sender, EventArgs e)
        {
            string xNum = xNumText.Text;
            string yNum = yNumText.Text;
            string widthNum = widthNumText.Text;
            string heightNum = heightNumText.Text;
            string apiKey = apiKeyText.Text;
            string secretKey = secretKeyText.Text;
            if (string.IsNullOrEmpty(xNum) || string.IsNullOrEmpty(yNum) || string.IsNullOrEmpty(widthNum) || string.IsNullOrEmpty(heightNum))
            {
                ShowWarningTip("坐标信息不能为空！");
                return;
            }
            iNIFile.IniWriteValue("CutPosition", "xNum", xNum);
            iNIFile.IniWriteValue("CutPosition", "yNum", yNum);
            iNIFile.IniWriteValue("CutPosition", "widthNum", widthNum);
            iNIFile.IniWriteValue("CutPosition", "heightNum", heightNum);
            iNIFile.IniWriteValue("BaiDuApiKey", "apiKey", apiKey);
            iNIFile.IniWriteValue("BaiDuApiKey", "secretKey", secretKey);
            ShowSuccessTip("保存成功！");
        }

        private void xNumText_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyValue == 13)
            {
                xNumText.Text = Cursor.Position.X.ToString();
                yNumText.Text = Cursor.Position.Y.ToString();
            }
        }

        private void yNumText_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyValue == 13)
            {
                xNumText.Text = Cursor.Position.X.ToString();
                yNumText.Text = Cursor.Position.Y.ToString();
            }
        }

        private void keyQueryBtn_Click(object sender, EventArgs e)
        {
            string msg = "复制网址，在百度创建文字识别应用，需要注册为开发者\n";
            msg += "教程网址：\nhttps://blog.csdn.net/asd497907957/article/details/120360262";
            ShowInfoDialog("提示", msg, UIStyle.Office2010Silver, false);
        }

        private void usageMethodBtn_Click(object sender, EventArgs e)
        {
            string msg = "X/Y坐标获取方法：鼠标选中X/Y坐标的输入框，点击出现闪烁的光标，然后将鼠标移到需要截图地方的左上角，按回车即可获取坐标。\n";
            msg += "宽度高度获取方法：用QQ截图或者其他截图方式选择要截图的区域，会显示一个宽高比，例如582×82，前面为宽后面为高，填入对应的输入框。";
            ShowInfoDialog("提示", msg, UIStyle.Office2010Silver, false);
        }

        private void feedbackBtn_Click(object sender, EventArgs e)
        {
            string msg = "①JX3BOX中留言反馈：\n";
            msg += "https://www.jx3box.com/tool/30669 \n";
            msg += "②贴吧中留言反馈：\n";
            msg += "https://tieba.baidu.com/p/7540226309?red_tag=2900722221 \n";
            msg += "③QQ群中反馈，群号：1004656865";
            ShowInfoDialog("提示", msg, UIStyle.Office2010Silver, false);
        }

        private void ErrorTip(string errorMsg)
        {
            answerText.ForeColor = Color.Red;
            answerText.Text = errorMsg;
        }

        private void openSourceBtn_Click(object sender, EventArgs e)
        {
            string msg = "如果大家有码云（gitee）帐号，请帮忙点个star，感谢！\n";
            msg += "码云（gitee）地址：https://gitee.com/yinchen001/JX3Answering\n";
            msg += "\n--by 音尘";
            ShowInfoDialog("提示", msg, UIStyle.Office2010Silver, false);
        }

        private void contentText_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyValue == 13)
            {
                FindAnswerBtn_Click(null, null);
            }
        }

        private bool QueryAnswering(string keyword)
        {
            answerText.ForeColor = Color.Black;
            string url;
            string result;
            if (dailyRadioBtn.Checked)
            {
                url = "https://w.pvp.xoyo.com:31727/api/h5/zhijian/tools/list/questions";
                string json = @"{""cursor"": 0,""size"": 300,""search"": """ + keyword + @""",""game"": ""jx3""}";
                result = HttpHelper.PostForBody(url, json);
                DailyAnswerEntity dailyAnswerEntity = new DailyAnswerEntity();
                dailyAnswerEntity = ConvertJson.DeserializeJsonToObject<DailyAnswerEntity>(result);
                if (dailyAnswerEntity.data.data.Count == 0)
                {
                    //loadingProcessBar.Visible = false;
                    //ErrorTip("暂未找到答案！注意关键字是否正确或者在剑网三推栏中进行反馈。");
                    return true;
                }
                int index = dailyAnswerEntity.data.data.Count;
                if (dailyAnswerEntity.data.data.Count > 10)
                {
                    index = 10;
                }
                for (int i = 0; i < index; i++)
                {
                    titleText.Text += dailyAnswerEntity.data.data[i].questions + "\r\n";
                    titleText.Text += "答案：" + dailyAnswerEntity.data.data[i].answer + "\r\n";
                }
                answerText.Text = dailyAnswerEntity.data.data[0].answer;
            }
            if (mingYiRadioBtn.Checked)
            {
                url = "https://pull.j3cx.com/api/exam";
                string postDataStr = $"search={keyword}";
                result = HttpHelper.HttpGet(url, postDataStr);
                AnswerEntity answerEntity = new AnswerEntity();
                answerEntity = ConvertJson.DeserializeJsonToObject<AnswerEntity>(result);
                if (answerEntity.data == null)
                {
                    //loadingProcessBar.Visible = false;
                    //ErrorTip("暂未找到答案！注意关键字是否正确。");
                    return true;
                }
                int answerNum;
                string[] options;
                int index = answerEntity.data.Count;
                if (answerEntity.data.Count > 10)
                {
                    index = 10;
                }
                for (int i = 0; i < index; i++)
                {
                    titleText.Text += answerEntity.data[i].title + "\r\n";
                    if (answerEntity.data[i].answers == "[]")
                    {
                        //loadingProcessBar.Visible = false;
                        //ErrorTip("暂未找到答案！你可以尝试选择另外的题库。");
                        return true;
                    }
                    answerNum = Convert.ToInt32(answerEntity.data[i].answers.Replace("[", "").Replace("]", ""));
                    options = answerEntity.data[i].options.Split(",");
                    titleText.Text += "答案：" + options[answerNum].Replace(@"[""", "").Replace(@"""]", "").Replace(@"""", "") + "\r\n";
                }
                answerNum = Convert.ToInt32(answerEntity.data[0].answers.Replace("[", "").Replace("]", ""));
                options = answerEntity.data[0].options.Split(",");
                answerText.Text = options[answerNum].Replace(@"[""", "").Replace(@"""]", "").Replace(@"""", "");
            }
            loadingProcessBar.Visible = false;
            return false;
        }

        private void AnswertMain_Load(object sender, EventArgs e)
        {
            X = this.Width;//赋值初始窗体宽度
            Y = this.Height;//赋值初始窗体高度
            setTag(this);
        }

        private void AnswertMain_Resize(object sender, EventArgs e)
        {
            float newX = this.Width / X;//获取当前宽度与初始宽度的比例
            float newY = this.Height / Y;//获取当前高度与初始高度的比例
            setControls(newX, newY, this);
        }
        //自定义方法setTag（获取控件的width、height、left、top、字体大小等信息的值）
        private void setTag(Control cons)
        {//遍历窗体中的控件
            foreach (Control con in cons.Controls)
            {
                con.Tag = con.Width + ":" + con.Height + ":" + con.Left + ":" + con.Top + ":" + con.Font.Size;
                if (con.Controls.Count > 0)
                {
                    setTag(con);
                }
            }
        }
        //自定义方法setControls（根据窗体大小调整控件大小）
        private void setControls(float newX, float newY, Control cons)
        {
            //遍历窗体中的控件，重新设置控件的值
            foreach (Control con in cons.Controls)
            {
                string[] mytag = con.Tag.ToString().Split(new char[] { ':' });//获取控件的Tag属性值，并分割后存储字符串数组

                float a = Convert.ToSingle(mytag[0]) * newX;//根据窗体缩放比例确定控件的值，宽度//89*300
                con.Width = (int)(a);//宽度

                a = Convert.ToSingle(mytag[1]) * newY;//根据窗体缩放比例确定控件的值，高度//12*300
                con.Height = (int)(a);//高度

                a = Convert.ToSingle(mytag[2]) * newX;//根据窗体缩放比例确定控件的值，左边距离//
                con.Left = (int)(a);//左边距离

                a = Convert.ToSingle(mytag[3]) * newY;//根据窗体缩放比例确定控件的值，上边缘距离
                con.Top = (int)(a);//上边缘距离

                Single currentSize = Convert.ToSingle(mytag[4]) * newY;//根据窗体缩放比例确定控件的值，字体大小
                con.Font = new Font(con.Font.Name, currentSize, con.Font.Style, con.Font.Unit);//字体大小

                if (con.Controls.Count > 0)
                {
                    setControls(newX, newY, con);
                }

                //Remarks：
                //控件当前宽度：控件初始宽度=窗体当前宽度：窗体初始宽度
                //控件当前宽度=控件初始宽度*(窗体当前宽度/窗体初始宽度)
            }
        }
        /// <summary>
        /// 勾选开启自动查找
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void loopAutoFindCheck_CheckedChanged(object sender, EventArgs e)
        {
            Task.Factory.StartNew(() =>
            {
                while (loopAutoFindCheck.Checked)
                {
                    try
                    {
                        Action action = () =>
                        {
                            autoFindAnswerBtn_Click(null, null);
                        };
                        Invoke(action);
                    }
                    catch (Exception exc)
                    {

                    }
                    finally
                    {
                        Thread.Sleep(1000);
                    }
                }
            }, TaskCreationOptions.LongRunning);


        }
        /// <summary>
        /// 更新当月API次数
        /// </summary>
        private void UpdateCurrentMonthApiNum()
        {
            string oldMonth = iNIFile.IniReadValue("QueryFrequency", "currentMonth");
            string currentMonth = DateTime.Now.Month.ToString();
            if (currentMonth != oldMonth)
            {
                iNIFile.IniWriteValue("QueryFrequency", "currentMonth", currentMonth);
                iNIFile.IniWriteValue("QueryFrequency", "queryNum", "0");
            }
            string oldQueryNum = iNIFile.IniReadValue("QueryFrequency", "queryNum");
            string newQueryNum = (Convert.ToInt32(oldQueryNum) + 1).ToString();
            apiNumText.Text = newQueryNum;
            iNIFile.IniWriteValue("QueryFrequency", "queryNum", newQueryNum);
        }

        
    }
}
